home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / misc / o-z / x-windows / mesa-amiwin / src / xfonts.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-03  |  9.2 KB  |  333 lines

  1. /* xfonts.c -- glXUseXFont() for Mesa
  2.    Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2 of the License, or
  7.    (at your option) any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; see the file COPYING.  If not, write to
  16.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.  */
  19.  
  20.  
  21.  
  22. static char *RCS_Id =
  23. "@(#) $Id: xfonts.c,v 1.6 1995/11/02 14:56:06 brianp Exp $";
  24.  
  25. /*
  26. $Id: xfonts.c,v 1.6 1995/11/02 14:56:06 brianp Exp $
  27.  
  28. $Log: xfonts.c,v $
  29.  * Revision 1.6  1995/11/02  14:56:06  brianp
  30.  * added (GLubyte *) cast per Steven Spitz
  31.  *
  32.  * Revision 1.5  1995/07/24  20:35:20  brianp
  33.  * replaced memset() with MEMSET() and memcpy() with MEMCPY()
  34.  *
  35.  * Revision 1.4  1995/07/21  16:25:46  brianp
  36.  * replaced XFreeFont() with XFreeFontInfo() per Kevin Adams
  37.  *
  38.  * Revision 1.3  1995/04/17  13:58:52  brianp
  39.  * changed CC->window to CC->frontbuffer
  40.  *
  41.  * Revision 1.2  1995/03/13  15:23:24  brianp
  42.  * Changed XSetForeground to hardcoded values
  43.  *
  44.  * Revision 1.1  1995/03/13  15:20:34  brianp
  45.  * Initial revision
  46.  *
  47.  */
  48.  
  49.  
  50.  
  51. #include <stdio.h>
  52. #include <stdlib.h>
  53. #include <string.h>
  54. #include <X11/Xlib.h>
  55. #include <X11/Xutil.h>
  56. #include <GL/gl.h>
  57. #include <GL/xmesa.h>
  58. #include "macros.h"
  59.  
  60. /* Some debugging info.  */
  61.  
  62. #ifdef DEBUG
  63. #include <ctype.h>
  64.  
  65. int debug_xfonts = 0;
  66.  
  67. static void
  68. dump_char_struct (XCharStruct *ch, char *prefix)
  69. {
  70.   printf ("%slbearing = %d, rbearing = %d, width = %d\n",
  71.       prefix, ch->lbearing, ch->rbearing, ch->width);
  72.   printf ("%sascent = %d, descent = %d, attributes = %u\n",
  73.       prefix, ch->ascent, ch->descent, ch->attributes);
  74. }
  75.  
  76. static void
  77. dump_font_struct (XFontStruct *font)
  78. {
  79.   int c;
  80.   
  81.   printf ("ascent = %d, descent = %d\n", font->ascent, font->descent);
  82.   printf ("char_or_byte2 = (%d,%d)\n",
  83.       font->min_char_or_byte2, font->max_char_or_byte2);
  84.   printf ("byte1 = (%d,%d)\n", font->min_byte1, font->max_byte1);
  85.   printf ("all_chars_exist = %s\n", font->all_chars_exist ? "True" : "False");
  86.   printf ("default_char = %c (\\%03o)\n",
  87.       isprint (font->default_char) ? font->default_char : ' ',
  88.       font->default_char);
  89.   dump_char_struct (&font->min_bounds, "min> ");
  90.   dump_char_struct (&font->max_bounds, "max> ");
  91. #if 0
  92.   for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++)
  93.     {
  94.       char prefix[8];
  95.       sprintf (prefix, "%d> ", c);
  96.       dump_char_struct (&font->per_char[c], prefix);
  97.     }
  98. #endif
  99. }
  100.  
  101. static void
  102. dump_bitmap (unsigned int width, unsigned int height, GLubyte *bitmap)
  103. {
  104.   int x, y;
  105.  
  106.   printf ("    ");
  107.   for (x = 0; x < 8*width; x++)
  108.     printf ("%o", 7 - (x % 8));
  109.   putchar ('\n');
  110.   for (y = 0; y < height; y++)
  111.     {
  112.       printf ("%3o:", y);
  113.       for (x = 0; x < 8*width; x++)
  114.         putchar ((bitmap[width*(height - y - 1) + x/8] & (1 << (7 - (x % 8))))
  115.          ? '*' : '.');
  116.       printf ("   ");
  117.       for (x = 0; x < width; x++)
  118.     printf ("0x%02x, ", bitmap[width*(height - y - 1) + x]);
  119.       putchar ('\n');
  120.     }
  121. }
  122. #endif /* DEBUG */
  123.  
  124.  
  125. /* Implementation.  */
  126.  
  127. /* Fill a BITMAP with a character C from thew current font
  128.    in the graphics context GC.  WIDTH is the width in bytes
  129.    and HEIGHT is the height in bits.
  130.  
  131.    Note that the generated bitmaps must be used with
  132.  
  133.     glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
  134.     glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
  135.     glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
  136.     glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
  137.     glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
  138.     glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
  139.  
  140.    Possible optimizations:
  141.  
  142.      * use only one reusable pixmap with the maximum dimensions.
  143.      * draw the entire font into a single pixmap (careful with
  144.        proportional fonts!).
  145. */
  146.  
  147. static void
  148. fill_bitmap (Display *dpy, Window win, GC gc,
  149.          unsigned int width, unsigned int height,
  150.          int x0, int y0, char c, GLubyte *bitmap)
  151. {
  152.   XImage *image;
  153.   int x, y;
  154.   Pixmap pixmap;
  155.  
  156.   pixmap = XCreatePixmap (dpy, win, 8*width, height, 1);
  157.   XSetForeground(dpy, gc, 0);
  158.   XFillRectangle (dpy, pixmap, gc, 0, 0, 8*width, height);
  159.   XSetForeground(dpy, gc, 1);
  160.   XDrawString (dpy, pixmap, gc, x0, y0, &c, 1);
  161.  
  162.   image = XGetImage (dpy, pixmap, 0, 0, 8*width, height, 1, XYPixmap);
  163.  
  164.   /* Fill the bitmap (X11 and OpenGL are upside down wrt each other).  */
  165.   for (y = 0; y < height; y++)
  166.     for (x = 0; x < 8*width; x++)
  167.       if (XGetPixel (image, x, y))
  168.     bitmap[width*(height - y - 1) + x/8] |= (1 << (7 - (x % 8)));
  169.   
  170.   XFreePixmap (dpy, pixmap);
  171.   XDestroyImage (image);
  172. }
  173.  
  174. #include "xmesaP.h"
  175. #include "context.h"
  176.  
  177. void
  178. glXUseXFont (Font font, int first, int count, int listbase)
  179. {
  180.   XMesaContext CC;
  181.   Display *dpy;
  182.   Window win;
  183.   Pixmap pixmap;
  184.   GC gc;
  185.   XGCValues values;
  186.   unsigned long valuemask;
  187.  
  188.   XFontStruct *fs;
  189.  
  190.   GLint swapbytes, lsbfirst, rowlength;
  191.   GLint skiprows, skippixels, alignment;
  192.  
  193.   unsigned int max_width, max_height, max_bm_width, max_bm_height;
  194.   GLubyte *bm;
  195.  
  196.   int i;
  197.  
  198.   CC = XMesaGetCurrentContext ();  
  199.   dpy = CC->display;
  200.   win = CC->frontbuffer;
  201.  
  202.   fs = XQueryFont (dpy, font);  
  203.   if (!fs)
  204.     {
  205.       gl_error (GL_INVALID_VALUE,
  206.         "Couldn't get font structure information");
  207.       return;
  208.     }
  209.  
  210.   /* Allocate a bitmap that can fit all characters.  */
  211.   max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
  212.   max_height = fs->max_bounds.ascent + fs->max_bounds.descent;
  213.   max_bm_width = (max_width + 7) / 8;
  214.   max_bm_height = max_height;
  215.  
  216.   bm = (GLubyte *) malloc ((max_bm_width * max_bm_height) * sizeof (GLubyte));
  217.   if (!bm)
  218.     {
  219.       gl_error (GL_OUT_OF_MEMORY,
  220.         "Couldn't allocate bitmap in glXUseXFont()");
  221.       return;
  222.     }
  223.  
  224.   /* Save the current packing mode for bitmaps.  */
  225.   glGetIntegerv    (GL_UNPACK_SWAP_BYTES, &swapbytes);
  226.   glGetIntegerv    (GL_UNPACK_LSB_FIRST, &lsbfirst);
  227.   glGetIntegerv    (GL_UNPACK_ROW_LENGTH, &rowlength);
  228.   glGetIntegerv    (GL_UNPACK_SKIP_ROWS, &skiprows);
  229.   glGetIntegerv    (GL_UNPACK_SKIP_PIXELS, &skippixels);
  230.   glGetIntegerv    (GL_UNPACK_ALIGNMENT, &alignment);
  231.  
  232.   /* Enforce a standard packing mode which is compatible with
  233.      fill_bitmap() from above.  This is actually the default mode,
  234.      except for the (non)alignment.  */
  235.   glPixelStorei    (GL_UNPACK_SWAP_BYTES, GL_FALSE);
  236.   glPixelStorei    (GL_UNPACK_LSB_FIRST, GL_FALSE);
  237.   glPixelStorei    (GL_UNPACK_ROW_LENGTH, 0);
  238.   glPixelStorei    (GL_UNPACK_SKIP_ROWS, 0);
  239.   glPixelStorei    (GL_UNPACK_SKIP_PIXELS, 0);
  240.   glPixelStorei    (GL_UNPACK_ALIGNMENT, 1);
  241.  
  242.   pixmap = XCreatePixmap (dpy, win, 10, 10, 1);
  243.   values.foreground = BlackPixel (dpy, DefaultScreen (dpy));
  244.   values.background = WhitePixel (dpy, DefaultScreen (dpy));
  245.   values.font = fs->fid;
  246.   valuemask = GCForeground | GCBackground | GCFont;
  247.   gc = XCreateGC (dpy, pixmap, valuemask, &values);
  248.   XFreePixmap (dpy, pixmap);
  249.  
  250. #ifdef DEBUG
  251.   if (debug_xfonts)
  252.     dump_font_struct (fs);
  253. #endif
  254.   
  255.   for (i = 0; i < count; i++)
  256.     {
  257.       unsigned int width, height, bm_width, bm_height;
  258.       GLfloat x0, y0, dx, dy;
  259.       XCharStruct *ch;
  260.       int x, y;
  261.       int c = first + i;
  262.       int list = listbase + i;
  263.  
  264.       if (fs->per_char
  265.       && (c >= fs->min_char_or_byte2) && (c <= fs->max_char_or_byte2))
  266.     ch = &fs->per_char[c-fs->min_char_or_byte2];
  267.       else
  268.     ch = &fs->max_bounds;
  269.  
  270. #ifdef DEBUG
  271.       if (debug_xfonts)
  272.     {
  273.       char s[7];
  274.       sprintf (s, isprint (c) ? "%c> " : "\\%03o> ", c);
  275.       dump_char_struct (ch, s);
  276.     }
  277. #endif
  278.       
  279.       /* glBitmap()' parameters:
  280.      straight from the glXUseXFont(3) manpage.  */
  281.       width = ch->rbearing - ch->lbearing;
  282.       height = ch->ascent + ch->descent;
  283.       x0 = - ch->lbearing;
  284.       y0 = ch->descent - 1;
  285.       dx = ch->width;
  286.       dy = 0;
  287.  
  288.       /* X11's starting point.  */
  289.       x = - ch->lbearing;
  290.       y = ch->ascent;
  291.       
  292.       /* Round the width to a multiple of eight.  We will use this also
  293.      for the pixmap for capturing the X11 font.  This is slightly
  294.      inefficient, but it makes the OpenGL part real easy.  */
  295.       bm_width = (width + 7) / 8;
  296.       bm_height = height;
  297.  
  298.       glNewList (list, GL_COMPILE);
  299.         if ((c >= fs->min_char_or_byte2) && (c <= fs->max_char_or_byte2)
  300.         && (bm_width > 0) && (bm_height > 0))
  301.       {
  302.         MEMSET (bm, '\0', bm_width * bm_height);
  303.         fill_bitmap (dpy, win, gc, bm_width, bm_height, x, y, c, bm);
  304.         glBitmap (width, height, x0, y0, dx, dy, bm);
  305. #ifdef DEBUG
  306.         if (debug_xfonts)
  307.           {
  308.         printf ("width/height = %d/%d\n", width, height);
  309.         printf ("bm_width/bm_height = %d/%d\n", bm_width, bm_height);
  310.         dump_bitmap (bm_width, bm_height, bm);
  311.           }
  312. #endif
  313.       }
  314.     else
  315.       glBitmap (0, 0, 0.0, 0.0, dx, dy, NULL);
  316.       glEndList ();
  317.     }
  318.  
  319.   free (bm);
  320.   XFreeFontInfo( NULL, fs, 0 );
  321.   XFreeGC (dpy, gc);
  322.  
  323.   /* Restore saved packing modes.  */    
  324.   glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
  325.   glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
  326.   glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
  327.   glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
  328.   glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
  329.   glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
  330. }
  331.  
  332. /* The End. */
  333.